#ifndef __COVARIANCE__
#define __COVARIANCE__

#include <vector>
#include <iostream>
#include <cassert>

using namespace std;





/*!
  \brief class for Covariance matrix


  Implementation of 2D symmetric square matrix via vector,
  used to store and compute covariance matrix of multiple variables
*/

class Covariance
{
 public:

  Covariance(int rank_=1);
  //!< default constructor, supply the rank of matrix

  bool Read(char* input);
  //!< fill covariance matrix from file
  //!< returns true if successful
 
  int Rank() const
  {return rank;}
  //!< return rank of tensor

  double Correlation(int row, int col) const;
  //!< return correlation for variable at row and col

  double operator()(int row, int col) const;
  //!< return covariance matrix elements
  //!< this DOES NOT access elements of ary

  double mean(int row) const;
  //!< return the mean


  Covariance& operator+=(const Covariance& input);
  //!< add another covariance matrix

  void Fill(const vector<double>& ntuple, double weight=1.0);
  //!< fill covariance with entry and weight
  //!< vector is used to enforce safety
  
  friend ostream& operator<<(ostream&, const Covariance&);
  //!< streaming operator for printing matrices


 protected:
  vector<double> ary2; 
  //!< vector implementation for 2D matrix
  //!< stores sum of xy
  //!< this is NOT the same as the covariance matrix

  vector<double> ary;
  //!< stores sum of x

  int rank; //!< rank of matrix (not the same as tensor rank)
  double sum; //!< sum of weights or number of entries in covariance matrix
  double sum2; //!< sum of weights^2 or (number of entries)^2 in covariance matrix
  //!< coefficient for variance computation
  //!< computed in ComputeBandwidth

};



#endif
